/**
 * Copyright (C) 2017 - 2020 https://github.com/joewee
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.wechat.controller;

import com.bifrost.common.constant.SessionConstant;
import com.bifrost.wechat.service.Oauth2Service;
import com.bifrost.wechat.service.WxServiceContext;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * @author joewee
 * @version 1.0.0
 * @Date 2017/11/25 11:50
 */
public abstract class AbstractOauth2Controller {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxServiceContext wxServiceContext;
    @Autowired
    Oauth2Service oauth2Service;

    @GetMapping("/authorize/{id}")
    public String authorize(@PathVariable("id")String id , @RequestParam String code, @RequestParam String state, HttpServletRequest request, HttpServletResponse response) {
        try {
            WxMpService wxService =null;
            if(StringUtils.length(StringUtils.trimToEmpty(id))<=8){
                wxService = wxServiceContext.getWxServiceByStoreCode(id);
            }
            else{
                wxService = wxServiceContext.getWxServiceByAppId(id);
            }
            WxMpOAuth2AccessToken auth2AccessToken = null;
            try {
                auth2AccessToken = wxService.oauth2getAccessToken(code);
            } catch (WxErrorException e) {
                logger.error(e.getMessage(),e);
                wxServiceContext.remove(id);
            }
            if(logger.isDebugEnabled()){
                logger.debug("accessToken：" + auth2AccessToken.toString());
            }
            if (auth2AccessToken != null) {
                WxMpUser user = wxService.oauth2getUserInfo(auth2AccessToken, "zh_CN");
                //将appId传到客户端cookie中，在SESSION失效时可用做登录判断是哪个公众号的依据
                String appId = wxService.getWxMpConfigStorage().getAppId();
                setCookie(request,response, SessionConstant.APP_ID,appId,24*3600);
                //oauth2Service.publishEvent(user,id);
               String url = this.doExtension(user,appId, state,request,response);
                if (StringUtils.isNotEmpty(url)) {
                    return url;
                }
            }
        } catch (WxErrorException e) {
            logger.info(e.getMessage(), e);
        }
        return String.format("redirect:%s",state);
    }

    /**
     * 扩展操作，如获取unionid，返回为非空时覆盖authorize方法
     * @param user
     * @param id
     * @param request
     * @param response
     * @return
     */
    public abstract String doExtension(WxMpUser user,String id ,String state,HttpServletRequest request, HttpServletResponse response);
    public void setCookie(HttpServletRequest request,HttpServletResponse response,String name,String value,int maxAge){
        try {
            value = URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 开始保存Cookie
        Cookie cookie = new Cookie(name, value);
        // 设置生命周期
        cookie.setMaxAge(maxAge);
        // cookie有效路径是网站根目录
        cookie.setPath(request.getContextPath());
        // 向客户端写入
        response.addCookie(cookie);
    }
}
